<?php
    /**
     * Created by PhpStorm.
     * User: mybook-lhp
     * Date: 18/4/18
     * Time: 下午4:29
     */

    namespace app\payment\logic;

    /**
     * 微信支付原始写法类
     * Class PayWechatOriginal
     *
     * @package Home\Logic
     */
    class PayWechatOriginal extends PayBase
    {

        protected $order = [];

        protected $nonce_str11 = '';

        protected $data = [];

        /**
         *  微信支付
         * se_number  订单编号
         * openid
         * p_money 支付金额
         */
        public function send($order_sn,$money)
        {

            $config = module_config('payment');
            //            echo json_encode($config);
            //            exit;
            $this->order['order_sn']   = $order_sn;
            $this->order['appid']      = $config['wxpay_app_id'];//APPID
            $this->order['nunber_mch'] = $config['wxpay_mch_id'];//商户ID
            $this->order['mch_key']    = $config['wxapy_mch_key'];//商户秘钥
            $this->order['total_fee']  = $money; //交易金额

            $this->order['notify_url'] = request()->domain() . self::Wechatpay_Notify_Url;
            $this->nonce_str11         = $this->nonce_str11();
            return $this->wx_pay();
        }

        //随机32位字符串
        private function nonce_str11()
        {

            $result = '';
            $str    = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';
            for ($i = 0; $i < 32; $i++)
            {
                $result .= $str[rand(0,48)];
            }
            return $result;
        }

        /**
         * 获取签名
         *
         * @param $params
         *
         * @return string
         */
        private function getSign($params)
        {

            ksort($params);        //将参数数组按照参数名ASCII码从小到大排序
            foreach ($params as $key => $item)
            {
                if (!empty($item))
                {         //剔除参数值为空的参数
                    $newArr[] = $key . '=' . $item;     // 整合新的参数数组
                }
            }
            $stringA        = implode("&",$newArr);         //使用 & 符号连接参数
            $stringSignTemp = $stringA . "&key=" . $this->order['mch_key']; //拼接key
            // key是在商户平台API安全里自己设置的
            $stringSignTemp = MD5($stringSignTemp);       //将字符串进行MD5加密
            $sign           = strtoupper($stringSignTemp);      //将所有字符转换为大写
            return $sign;
        }

        public function wx_pay()
        {

            $nonce_str                = $this->rand_code();        //调用随机字符串生成方法获取随机字符串
            $data['appid']            = $this->order['appid'];   //appid
            $data['mch_id']           = $this->order['nunber_mch'];        //商户号
            $data['body']             = self::Body;
            $data['spbill_create_ip'] = get_client_ip();   //ip地址
            $data['total_fee']        = $this->order['total_fee'];  //金额
            $data['out_trade_no']     = $this->order['order_sn'];      //商户订单号,不能重复
            $data['nonce_str']        = $nonce_str;            //随机字符串
            $data['notify_url']       = request()->domain() . self::Wechatpay_Notify_Url; //回调地,用户接收支付后的通知,必须为能直接访问的网址,不能跟参数

            $data['trade_type'] = 'APP';      //支付方式
            //将参与签名的数据保存到数组  注意：以上几个参数是追加到$data中的，$data中应该同时包含开发文档中要求必填的剔除sign以外的所有数据
            $data['sign'] = $this->getSign($data);        //获取签名
            $xml          = $this->ToXml($data);            //数组转xml
            //curl 传递给微信方
            $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

            //header("Content-type:text/xml");
            $ch = curl_init();
            curl_setopt($ch,CURLOPT_URL,$url);
            if (stripos($url,"https://") !== FALSE)
            {
                curl_setopt($ch,CURLOPT_SSLVERSION,CURL_SSLVERSION_TLSv1);
                curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
                curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
            }
            else
            {
                curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
                curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
            }
            //设置header
            curl_setopt($ch,CURLOPT_SSLVERSION,CURL_SSLVERSION_TLSv1);
            curl_setopt($ch,CURLOPT_HEADER,FALSE);
            //要求结果为字符串且输出到屏幕上
            curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
            //设置超时
            curl_setopt($ch,CURLOPT_TIMEOUT,30);
            curl_setopt($ch,CURLOPT_POST,TRUE);
            //传输文件
            curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
            //运行curl
            $data = curl_exec($ch);
            //返回结果
            if ($data)
            {
                curl_close($ch);
                //返回成功,将xml数据转换为数组.
                $re = $this->FromXml($data);
                if ($re['return_code'] != 'SUCCESS')
                {
                    return $re;
                }
                else
                {
                    //接收微信返回的数据,传给APP!
                    $arr = [
                        'prepayid'  => $re['prepay_id'],
                        'appid'     => $this->order['appid'],
                        'partnerid' => $this->order['nunber_mch'],
                        'package'   => 'Sign=WXPay',
                        'noncestr'  => $nonce_str,
                        'timestamp' => time(),
                    ];
                    //第二次生成签名
                    $sign        = $this->getSign($arr);
                    $arr['sign'] = $sign;
                    return $arr;
                }
            }
            else
            {
                $error = curl_errno($ch);
                curl_close($ch);
                return $error;
            }
        }

        /**
         * 获取随机数
         *
         * @return bool|string
         */
        function rand_code()
        {

            $str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';//62个字符
            $str = str_shuffle($str);
            $str = substr($str,0,32);
            return $str;
        }

        /**
         * XML 转数组
         *
         * @param $xml
         *
         * @return mixed
         */
        public function FromXml($xml)
        {

            if (!$xml)
            {
                die('xml数据异常！');
            }
            //将XML转为array
            //禁止引用外部xml实体
            libxml_disable_entity_loader(true);
            $data = json_decode(json_encode(simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOCDATA)),true);
            return $data;
        }

        /**
         * 数组转Xml
         *
         * @param array $data
         * @param bool  $is_cdata
         *
         * @return string
         */
        public function ToXml($data = [],$is_cdata = false)

        {

            if (!is_array($data) || count($data) <= 0)
            {
                return '数组异常';
            }

            $xml = "<xml>";
            foreach ($data as $key => $val)
            {
                if ($is_cdata)
                {
                    $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
                }
                else
                {
                    if (is_numeric($val))
                    {
                        $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
                    }
                    else
                    {
                        $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
                    }
                }
            }
            $xml .= "</xml>";
            return $xml;
        }
    }